package com.pactera.asmp.server.restfullapi;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.pactera.asmp.server.common.constants.Constants;
import com.pactera.asmp.server.common.constants.PermissionCode;
import com.pactera.asmp.server.common.constants.ResultCode;
import com.pactera.asmp.server.common.logprint.utils.StringUtils;
import com.pactera.asmp.server.entity.ResponseResult;
import com.pactera.asmp.server.entity.ScriptInfoDTO;
import com.pactera.asmp.server.entity.ScriptInfoSearchDTO;
import com.pactera.asmp.server.pojo.ScriptInfo;
import com.pactera.asmp.server.service.IScriptInfoHistoryService;
import com.pactera.asmp.server.service.ScriptInfoServcieImpl;
import com.pactera.asmp.server.utils.PageDataResult;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

/**
 * @ProjectName: tlsserver
 * @Package com.pactera.asmp.server.restfullapi
 * @ClassName: RestfullScriptApi
 * @Description: 脚本存储
 * @Date 2020/06/01 11:05
 * @Author lvzhiqiang
 * @Version 1.0
 */
@RestController
@RequestMapping("/api/v1")
public class RestfullScriptApi {

    private static final Logger logger = LoggerFactory
            .getLogger(RestfullScriptApi.class);

    @Autowired
    private ScriptInfoServcieImpl mScriptInfoServiceImpl;

    @Autowired
    private IScriptInfoHistoryService scriptInfoHistoryService;

    @RequiresPermissions({PermissionCode.TEST_CASE})
    @PostMapping(value = "/script/list",produces = "application/json;charset=UTF-8")
    public ResponseResult getScriptList(@RequestBody ScriptInfoSearchDTO scriptInfoSearchDTO) {
        logger.info("POST /api/v1/script/list getScriptList" );
        ResponseResult responseResult = new ResponseResult(ResultCode.SUCCESS);
        PageDataResult pdr ;
        if (null == scriptInfoSearchDTO.getPage() || scriptInfoSearchDTO.getPage().intValue() == 0) {
            scriptInfoSearchDTO.setPage(1);
        }
        if (null == scriptInfoSearchDTO.getLimit() || scriptInfoSearchDTO.getLimit().intValue() == 0) {
            scriptInfoSearchDTO.setLimit(10);
        }

        if(scriptInfoSearchDTO.getPage().intValue() < 0 || scriptInfoSearchDTO.getLimit().intValue() < 0) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("totals", 0);
            jsonObject.put("list", Lists.newArrayList());
            responseResult.setData(jsonObject);
            return responseResult;
        }
        pdr = mScriptInfoServiceImpl.select(scriptInfoSearchDTO);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("totals", pdr.getTotals());
        jsonObject.put("list", pdr.getList());
        responseResult.setData(jsonObject);
        return responseResult;
    }

    @PostMapping(value = "/script")
    public ResponseResult addScript(@RequestBody ScriptInfoDTO scriptInfoDTO) {
        logger.info("POST /api/v1/script addScript");
        if (null == scriptInfoDTO) {
            return new ResponseResult(ResultCode.PARAM_IS_BLANK);
        }
        if (StringUtils.isEmpty(scriptInfoDTO.getDeviceId()) || StringUtils.isEmpty(scriptInfoDTO.getDuid())
                || StringUtils.isEmpty(scriptInfoDTO.getName())
                || StringUtils.isEmpty(scriptInfoDTO.getScriptCategory())
                || scriptInfoDTO.getProjectModuleId() == null
                || scriptInfoDTO.getScriptData() == null) {
            return new ResponseResult(ResultCode.PARAM_NOT_COMPLETE);
        }
        if(!scriptInfoDTO.getName().matches(Constants.REGEXP_FIRST_LAST_NOT_SPACE)) {
            return new ResponseResult(ResultCode.PARAM_TYPE_BIND_ERROR);
        }
        ScriptInfoDTO infoDTO = mScriptInfoServiceImpl.insert(scriptInfoDTO);
        return ResponseResult.defaultSuccess(infoDTO.getId());
    }


    @PutMapping(value = "/script",  produces = "application/json;charset=UTF-8")
    public ResponseResult updateScript(@RequestBody ScriptInfo scriptInfo) {
        logger.info("PUT /api/v1/script");
        if (scriptInfo == null || scriptInfo.getId() == null || StringUtils.isEmpty(scriptInfo.getDeviceId()) || StringUtils.isEmpty(scriptInfo.getDuid())
                || StringUtils.isEmpty(scriptInfo.getName())
                || StringUtils.isEmpty(scriptInfo.getScriptCategory())
                || scriptInfo.getProjectModuleId() == null
                || scriptInfo.getScriptData() == null) {
            return new ResponseResult(ResultCode.PARAM_IS_BLANK);
        }
        if (StringUtils.isNotEmpty(scriptInfo.getName())) {
            if(!scriptInfo.getName().matches(Constants.REGEXP_FIRST_LAST_NOT_SPACE)) {
                return new ResponseResult(ResultCode.PARAM_TYPE_BIND_ERROR);
            }
        }
        handleUpdateTime(scriptInfo);
        return mScriptInfoServiceImpl.update(scriptInfo) ? new ResponseResult(ResultCode.SUCCESS) : new ResponseResult(ResultCode.SYSTEM_INNER_ERROR);
    }

    private void handleUpdateTime(ScriptInfo scriptInfo) {
        Date date = new Date();
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime updateTime = instant.atZone(zoneId).toLocalDateTime();
        scriptInfo.setUpdateTime(updateTime);
    }


    @PostMapping(value = "/script/delete", produces = "application/json;charset=UTF-8")
    public ResponseResult deleteScript(@RequestBody List<Integer> datas) {
        logger.info("delete /api/v1/script deleteScript ");
        if (datas.isEmpty()) {
            return new ResponseResult(ResultCode.PARAM_IS_BLANK);
        }
        return mScriptInfoServiceImpl.delete(datas) ? new ResponseResult(ResultCode.SUCCESS) : new ResponseResult(ResultCode.SYSTEM_INNER_ERROR);
    }

    /**
     * @api {GET} /api/v1/historyScript/list getHistoryScriptList
     * @apiVersion 1.0.0
     * @apiGroup RestfullScriptApi
     * @apiName getHistoryScriptList
     * @apiDescription 分页获取脚本更改历史记录数据
     * @apiParam (请求参数) {Number} scriptId 脚本表主键
     * @apiParam (请求参数) {Number} page 页号
     * @apiParam (请求参数) {Number} limit 页大小
     * @apiParamExample 请求参数示例
     * scriptId=1372&limit=9361&page=7478
     * @apiSuccess (响应结果) {Number} code
     * @apiSuccess (响应结果) {String} message
     * @apiSuccess (响应结果) {Object} data
     * @apiSuccessExample 响应结果示例
     * {"code":9057,"data":{},"message":"KqRC"}
     */
    @RequiresPermissions({PermissionCode.TEST_CASE})
    @GetMapping("/historyScript/list")
    public ResponseResult getHistoryScriptList(Integer scriptId, Integer page, Integer limit) {
        ResponseResult responseResult = new ResponseResult(ResultCode.SUCCESS);
        logger.info("GET /api/v1/historyScript/list getHistoryScriptList" );
        if (null == page || page.intValue() == 0) {
            page = 1;
        }
        if (null == limit || limit.intValue() == 0) {
            limit = 10;
        }
        if(page.intValue() < 0 || limit.intValue() < 0) {
            responseResult.setData(new PageDataResult(0, Lists.newArrayList()));
            return responseResult;
        }
        PageDataResult pdr = scriptInfoHistoryService.selective(scriptId, page, limit);
        responseResult.setData(pdr);
        return responseResult;
    }

    @GetMapping(value = "/script/relConstant", produces = "application/json;charset=UTF-8")
    public ResponseResult getRelConstantList(Integer scriptId) {
        logger.info("POST /api/v1/script/relConstant getRelConstantList" );
        ResponseResult responseResult = new ResponseResult(ResultCode.SUCCESS);
        List<Long> scriptInfoList = mScriptInfoServiceImpl.selectRelConstantList(scriptId);
        responseResult.setData(CollectionUtils.isEmpty(scriptInfoList) ? Lists.newArrayList() : scriptInfoList);
        return responseResult;
    }

}
